<!DOCTYPE html>
<html lang='en'>

<head>
    <meta charset='UTF-8'>
    <meta http-equiv='X-UA-Compatible' content='IE=edge'>
    <meta name='viewport' content='width=device-width, initial-scale=1.0'>
    <title>Document</title>
    <script src='../vue.global.js'></script>
    <style>
        .divider {
            border-bottom: 1px solid #000;
        }
    </style>
</head>

<body>
    <div id="app"></div>

    <script>
        /* 基于根组件创建应用实例app */
        const app = Vue.createApp({

            // 组件模板
            template:`
            <!-- 用户输入表单 提交时调用addTodo （利用事件修饰符prevent阻止表单的默认提交事件）-->
            <form @submit.prevent="addTodo">

                <!-- 将用户输入双向绑定到userInput -->
                <input type="text" v-model="userInput">

                <button>ADD</button>
            </form>
            <hr>

            <ul>
                <!-- 每个item渲染一个todo-item子组件 -->
                <!-- 将item作为名曰todo的props 给子组件传递 -->
                <!-- 接收子组件发布的remove自定义事件 调用函数处理之-->
                <!-- 
                    列表渲染中的key的作用 
                    用一个绝对唯一的标识对标完整的item视图 
                    做差量渲染时 对比新老DOM中每个item的key
                    key变则直接删除旧的item视图 重新绘制新的item
                    key不变则直接复用原有的item视图 
                -->
                <todo-item 
                    v-for="(item,index) in todos" 
                    :key="item.id" 
                    :todo="item" 
                    @remove="removeTodo(index)"
                ></todo-item>
            </ul>
            `,
            
            // 组件数据闭包
            data() {
                return {
                    // 双向绑定用户在input中的输入
                    userInput: '',

                    // 核心业务数据
                    todos: [
                        {
                            id: 1,
                            title: 'Do the dishes'
                        },
                        {
                            id: 2,
                            title: 'Take out the trash'
                        },
                        {
                            id: 3,
                            title: 'Mow the lawn'
                        }
                    ]
                }
            }
            ,

            // 组件方法
            methods: {
                // 处理表单提交
                addTodo(e) {
                    // 构造一个【待办事项】对象 添加到todos 组件视图会自动更新
                    this.todos.push({
                        id: Date.now()+parseInt(Math.random()*Math.pow(10,6))+'',
                        title: this.userInput
                    })

                    // 清空input框
                    this.userInput = ""
                },

                // 响应子组件发送的remove自定义事件 删除对应序号的【待办事项】 VM引擎驱动视图重新绘制
                removeTodo(index) {
                    this.todos.splice(index, 1)
                }
            }
        })

        /* 在应用实例中声明【全局组件】（谁用都不需要声明） */
        app.component(
            // 组件名称
            "todo-item",

            // 组件配置
            {
                // 渲染todo的标题
                template: `
                <li>
                    {{todo.title}}

                    <!-- 点击按钮时 向父组件发送自定义事件remove -->
                    <button @click="$emit('remove')">删除</button>
                </li>
                `,

                // 接收父组件传入的props名曰todo
                props: ["todo"],

                // 定义向父组件发送的自定义事件 怎么处理完全在于父组件
                emits: ["remove"]
            }
        )

        /* 将应用实例挂载到DOM中 返回根组件实例 */
        const vm = app.mount("#app")
    </script>

</body>

</html>